﻿namespace ClassyBlog.Web.Specs.Unit
{
    using System;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;

    using Machine.Specifications;
    using NSubstitute;

    using DomainObjects;
    using Infrastructure;

    public abstract class AssetHelperSpec
    {
        protected static HttpContextBase httpContext;
        protected static UrlHelper urlHelper;

        static IDependencyResolver previousDependencyResolver;

        Establish context = () =>
        {
            var currentBlogProvider = Substitute.For<ICurrentBlogProvider>();

            currentBlogProvider.Current.Returns(new Blog
                                                    {
                                                        Theme = "default"
                                                    });

            var dependencyResolver = Substitute.For<IDependencyResolver>();

            dependencyResolver.GetService(typeof(ICurrentBlogProvider))
                              .Returns(currentBlogProvider);

            previousDependencyResolver = DependencyResolver.Current;

            DependencyResolver.SetResolver(dependencyResolver);

            httpContext = MvcTestHelper.CreateHttpContext("http://localhost");

            urlHelper = new UrlHelper(
                new RequestContext(httpContext, new RouteData()));
        };

        Cleanup on_exit = () =>
            DependencyResolver.SetResolver(previousDependencyResolver);
    }

    [Subject(typeof(AssetHelper))]
    public class when_trying_to_request_stylesheet_file_of_an_null_instance
    {
        static UrlHelper urlHelper;
        static Exception exception;

        Establish context = () => urlHelper = null;

        Because of = () => exception =
            Catch.Exception(() => urlHelper.StyleSheet("application"));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(AssetHelper))]
    public class when_stylesheet_file_is_requested_in_debug_mode :
        AssetHelperSpec
    {
        static string stylesheetFile;

        Establish contenxt = () =>
            httpContext.IsDebuggingEnabled.Returns(true);

        Because of = () =>
            stylesheetFile = urlHelper.StyleSheet("application");

        It should_return_regular_version = () =>
            stylesheetFile.EndsWith("/assets/stylesheets/application.css")
                          .ShouldBeTrue();
    }

    [Subject(typeof(AssetHelper))]
    public class when_stylesheet_file_is_requested_in_production_mode :
        AssetHelperSpec
    {
        static string stylesheetFile;

        Because of = () =>
            stylesheetFile = urlHelper.StyleSheet("application");

        It should_return_minified_version = () =>
            stylesheetFile.EndsWith("/assets/stylesheets/application.min.css")
                          .ShouldBeTrue();
    }

    [Subject(typeof(AssetHelper))]
    public class when_trying_to_request_javascript_file_of_an_null_instance
    {
        static UrlHelper urlHelper;
        static Exception exception;

        Establish context = () => urlHelper = null;

        Because of = () => exception =
            Catch.Exception(() => urlHelper.JavaScript("application"));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(AssetHelper))]
    public class when_javascript_file_is_requested_in_debug_mode :
        AssetHelperSpec
    {
        static string javascriptFile;

        Establish contenxt = () =>
            httpContext.IsDebuggingEnabled.Returns(true);

        Because of = () =>
            javascriptFile = urlHelper.JavaScript("application");

        It should_return_regular_version = () =>
            javascriptFile.EndsWith("/assets/javascripts/application.js")
                          .ShouldBeTrue();
    }

    [Subject(typeof(AssetHelper))]
    public class when_javascript_file_is_requested_in_production_mode :
        AssetHelperSpec
    {
        static string javascriptFile;

        Because of = () =>
            javascriptFile = urlHelper.JavaScript("application");

        It should_return_minified_version = () =>
            javascriptFile.EndsWith("/assets/javascripts/application.min.js")
                          .ShouldBeTrue();
    }

    [Subject(typeof(AssetHelper))]
    public class when_trying_to_request_image_file_of_an_null_instance
    {
        static UrlHelper urlHelper;
        static Exception exception;

        Establish context = () => urlHelper = null;

        Because of = () => exception =
            Catch.Exception(() => urlHelper.Image("logo.png"));

        It should_throw_exception = () =>
            exception.ShouldBeOfType<ArgumentNullException>();
    }

    [Subject(typeof(AssetHelper))]
    public class when_image_file_is_requested : AssetHelperSpec
    {
        static string imageFile;

        Because of = () => imageFile =
            urlHelper.Image("logo.png");

        It should_return_minified_version = () =>
            imageFile.EndsWith("/assets/images/logo.png").ShouldBeTrue();
    }
}